/**
 * Copyright 2011 The Apache Software Foundation
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package idv.takeshi.persistence.dao.mybatis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.mybatis.spring.support.SqlSessionDaoSupport;

import idv.takeshi.model.Person;
import idv.takeshi.model.RoleRelationship;
import idv.takeshi.persistence.dao.PersonDao;

/**
 * @author takeshi.miao
 *
 */
public class PersonDaoImpl extends SqlSessionDaoSupport implements PersonDao {
	
	private static final String MAPPER_NAMESPACE = "idv.takeshi.persistence.dao.PersonDao.";

	/* (non-Javadoc)
	 * @see idv.takeshi.persistence.dao.PersonDao#add(idv.takeshi.model.Person)
	 */
	@Override
	public void add(Person person) {
		this.getSqlSession().insert(MAPPER_NAMESPACE + "add", person);
		
		Long newPersonId = null;
		newPersonId = (Long) this.getSqlSession().selectOne("getCurrrentSequence");
		person.setId(newPersonId);
		
		List<RoleRelationship> roleRelationships = null;
		roleRelationships = person.getRoleRelationships();
		
		insertRoleRelationships(person, roleRelationships);
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.persistence.dao.PersonDao#deleteById(java.lang.Long)
	 */
	@Override
	public void deleteById(Long id) {
		this.getSqlSession().delete(MAPPER_NAMESPACE + "deleteById", id);
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.persistence.dao.PersonDao#getAll()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<Person> getAll() {
		return this.getSqlSession().selectList(MAPPER_NAMESPACE + "getAll");
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.persistence.dao.PersonDao#getById(java.lang.Long)
	 */
	@Override
	public Person getById(Long id) {
		return (Person) this.getSqlSession().selectOne(MAPPER_NAMESPACE + "getById", id);
	}

	/* (non-Javadoc)
	 * @see idv.takeshi.persistence.dao.PersonDao#update(idv.takeshi.model.Person)
	 */
	@Override
	public void update(Person person) {
		//1. update person
		this.getSqlSession().update(MAPPER_NAMESPACE + "update", person);
		
		List<RoleRelationship> roleRelationships = null;
		roleRelationships = person.getRoleRelationships();
		
		//2. delete all roleRelationships
		this.getSqlSession().delete(MAPPER_NAMESPACE + "deleteRoleRelationship", person.getId());
		
		//3. re-insert roleRelationships
		insertRoleRelationships(person, roleRelationships);
	}

	private void insertRoleRelationships(
			Person person, List<RoleRelationship> roleRelationships) {
		RoleRelationship roleRelationship = null;
		Map<String, Object> paramsMap = null;
		
		//add all roleRelationships to DB 
		for(int a = 0; a < roleRelationships.size(); a++){
			roleRelationship = roleRelationships.get(a);
			roleRelationship.setPersonId(person.getId());
			
			paramsMap = new HashMap<String, Object>();
			paramsMap.put("personId", roleRelationship.getPersonId());
			paramsMap.put("roleId", roleRelationship.getRoleId());
			paramsMap.put("accountName", person.getAccountName());
			paramsMap.put("roleName", roleRelationship.getRole().getName());
			
			this.getSqlSession().insert(MAPPER_NAMESPACE + "addRoleRelationship", paramsMap);
		}
	}

	@Override
	public Person getByAccountName(String accountName) {
		return (Person) this.getSqlSession().selectOne(MAPPER_NAMESPACE + "getByAccountName", accountName);
	}

}
